#!/usr/bin/python
import json , re , sys , os , time
from logger import *
import ConfigParser

class Configger:

	default_logs_dir	= "../logs"
	default_conf_dir	= "../conf"
#	file_group_json		= "../conf/groups.json"
	file_server_conf	= "../conf/server.conf"
	groups_logger		= "groups.log"
	server_logger		= "server.log"
	server_struct		= {"defaults" : {"splitter":1,"epocs":1,"faults_min":1,"rate":1} , "globals" : {"logs_dir":0 , "pulse_sec":1 , "group_configs":1}}
	server_values		= {}

	def __init__(self,debug=False):
		self.user_conf = {}
		self.logger = Logger(self.default_logs_dir)
		if debug : self.logger.setVerbose()
		self.parse_server()

		#	Maybe logs location was changed	
		self.logger = Logger(self.server_values['logs_dir'])
		if debug : self.logger.setVerbose()	

	def parse_server(self):
		config = ConfigParser.RawConfigParser()
		config.read(self.file_server_conf)

		for k in self.server_struct :
			for kk in self.server_struct[k]:
				try:
					self.server_values[kk] = config.get(k , kk)
				except:
					if self.server_struct[k][kk] == 1 :
						self.logger._log(self.server_logger , "MISSING entry %s in %s section in server.conf. ABORTED" % (kk,k))
						print "ABORTED. see server.log"
						sys.exit(1)
					else : pass
		self.server_values_adjust()	


	def server_values_adjust(self):
		self.server_values["group_configs"] = self.server_values["group_configs"].replace(' ','').split(",")
		self.server_values["splitter"] 	= re.sub(r'\s','',self.server_values["splitter"])
		epocs				= self.server_values["epocs"].split(",")
		self.server_values["epocs"]	= [int(e) for e in epocs]
		self.server_values["faults_min"]= int(self.server_values["faults_min"])
		self.server_values["rate"]	= float(self.server_values["rate"])
		if "logs_dir" in self.server_values:
			self.server_values["logs_dir"]  = re.sub(r'\s','',self.server_values["logs_dir"])
		else : 
			self.server_values["logs_dir"]	= self.default_logs_dir
		self.server_values["pulse_sec"]= int(self.server_values["pulse_sec"])


	def parse_groups(self):
		self.user_conf["groups"] = {}
		for file in self.server_values["group_configs"] :
			try:
				f = open( "%s/%s" % (self.default_conf_dir , file) ,"r")
			except:
				self.logger._log(self.groups_logger , "%s/%s NOT EXISTS" % (self.default_conf_dir , file))
				continue
			str = ''
			for line in f : 
				l = line.replace('\\','\\\\')
				str += re.sub(r'([#;].*$|\n|\t|^\s+)','',l)
				str = re.sub(r',\s*([}{])','\\1',str)
			try:
				jl = json.loads(str)
				for group in jl["groups"]:
					self.user_conf["groups"][group] = jl["groups"][group]
			except:
				self.logger._log(self.groups_logger , "%s MISMATCH json format:\n\n%s" % (file,str))

		self.validate_groups()
		self.groups_conf()


	def validate_groups(self):
		delete_groups = []
		user_conf = self.user_conf["groups"]
		for group_name in user_conf:	
			if not "rates" in user_conf[group_name] : user_conf[group_name]["rates"] = {}
			if not "sumfields" in user_conf[group_name] : user_conf[group_name]["sumfields"] = {}

			sumfields = user_conf[group_name]["sumfields"].keys()
			sumfields.append("count")


			if  len(user_conf[group_name]['fields']) < 1	:
				self.logger._log(self.groups_logger , "in %s `fields` must be a list of log fields. group is IGNORED" % group_name)
				delete_groups.append(group_name)

			if "sql" in user_conf[group_name]:
				ignore_group_fields = ["minval"]
			else:
				ignore_group_fields = ["parser","minval","file"]

			for ff in ignore_group_fields:
				if not ff in user_conf[group_name]:
					self.logger._log(self.groups_logger , "in %s `%s` value MUST be set. group is IGNORED" % group_name,ff)
					delete_groups.append(group_name)

			if "parser" in user_conf[group_name] and user_conf[group_name]["parser"] == "regexparse" and not "regex" in user_conf[group_name]:
				self.logger._log(self.groups_logger , "in %s `regex` value MUST be set as the parser is `regexparse`. group is IGNORED" % group_name)

			if not "faults_min" in user_conf[group_name] : 
				self.logger._log(self.groups_logger , "WARNING.  in %s `faults_min` not specified will get default value defined in server.conf" % group_name)

			if "ssh" in user_conf[group_name] and "sql" in user_conf[group_name] :
				self.logger._log(self.groups_logger , "in %s Cant NOT run in SSH mode AND SQL mode. group is IGNORED" % (group_name))
                                delete_groups.append(group_name)

			if "ssh" in user_conf[group_name] :
				ssh_fields = ["user","host","passwd"]
				for k in ssh_fields:
					if not k in user_conf[group_name]["ssh"]:
						if k == "host" and "hosts" in user_conf[group_name]["ssh"] : continue
						user_conf[group_name]["ssh"][k] = ''
						self.logger._log(self.groups_logger , "WARNING.SSH  in %s `%s` field not set will be set to ''" % (group_name , k))

			if "sql" in user_conf[group_name] :
				sql_fields = ['table','host','port','db','user','password','rdbms','time_field']
				for k in sql_fields:
					if not k in user_conf[group_name]["sql"] :
						self.logger._log(self.groups_logger , "in %s `%s` value MUST be set. group is IGNORED" % (group_name,k))
						delete_groups.append(group_name)
				if not 'fix_times' in user_conf[group_name]["sql"] and (not 'seconds_offset' in user_conf[group_name]["sql"] or not 'seconds_range' in user_conf[group_name]["sql"]):
					self.logger._log(self.groups_logger , "in %s times ranges Must be set ('fix_times' or ('seconds_offset','seconds_range')). group is IGNORED" % (group_name))
					delete_groups.append(group_name)
				if 'fix_times' in user_conf[group_name]["sql"] and ('seconds_offset' in user_conf[group_name]["sql"] or 'seconds_range' in user_conf[group_name]["sql"]):
					self.logger._log(self.groups_logger , 
						"WARNING.SQL  in %s both 'time_field' and ('seconds_offset','seconds_range') defined. 'time_field' takes precedence" % (group_name))
				if 'fix_times' in user_conf[group_name]["sql"] and len(user_conf[group_name]["sql"]['time_field']) != 4:
					self.logger._log(self.groups_logger , "in %s field 'time_field' Must have 4 elements. group is IGNORED" %  (group_name))
					delete_groups.append(group_name) 

			for k in sumfields:
				if not k in user_conf[group_name]["rates"]:
					self.logger._log(self.groups_logger , "WARNING.  in %s `rates` of %s will get default value defined in server.conf" % (group_name , k))

		self.del_groups(delete_groups)


	def del_groups(self , delete_groups):	
		for k in delete_groups:
			if k in self.user_conf['groups']: del self.user_conf['groups'][k]


		
	def groups_conf(self):
		self.gc = {}
		for group_name in self.user_conf["groups"] :
			self.gc[group_name] = {}
			self.gc[group_name]["group_conf"] = {
                                "fields"        : self.user_conf["groups"][group_name]["fields"],
                                "splitter"      : self.user_conf["groups"][group_name]["splitter"] if "splitter" in self.user_conf["groups"][group_name] else self.server_values["splitter"],
                                "sumfields"     : self.user_conf["groups"][group_name]["sumfields"],
                                "epocs"         : self.user_conf["groups"][group_name]["spocs"] if "spocs" in self.user_conf["groups"][group_name] else self.server_values["epocs"],
                                "faults_min"    : self.user_conf["groups"][group_name]["faults_min"] if "faults_min" in self.user_conf["groups"][group_name] else self.server_values["faults_min"],
			}

			for ff in ["ssh","regex","filter","monitor","file","parser","sql","minval"]:
				if ff in self.user_conf["groups"][group_name]:
					self.gc[group_name]["group_conf"][ff] = self.user_conf["groups"][group_name][ff]


			rates = {}
			for k in self.user_conf["groups"][group_name]["sumfields"]:
				rates[k] = self.user_conf["groups"][group_name]["rates"][k] if k in self.user_conf["groups"][group_name]["rates"] else self.server_values["rate"]
			rates["count"] = self.user_conf["groups"][group_name]["rates"]["count"] if "count" in self.user_conf["groups"][group_name]["rates"] else self.server_values["rate"]

			self.gc[group_name]["compare_conf"] = {
				"minval"	: float(self.user_conf["groups"][group_name]["minval"]),
				"rates"		: rates
			}

			if "sql" in self.user_conf["groups"][group_name] :
				self.gc[group_name]["db_conf"] = self.user_conf["groups"][group_name]["sql"]
				del self.user_conf["groups"][group_name]["sql"]


	def is_config_changed(self):
		for file in self.server_values["group_configs"]:
			if os.path.isfile("%s/%s" % (self.default_conf_dir , file)) and \
				(int(time.time()) - os.path.getmtime("%s/%s" % (self.default_conf_dir , file)) < int(self.server_values["pulse_sec"])):
				return True
		return False

#############################################


